In modern computing systems, it is common to have an operating system that allows computer programs to be executed as multiple threads which share access to computing resources managed by the operating system. An operating system itself also can have multiple threads available for servicing requests from applications to operating system resources, herein called worker threads.
There are several ways to manage the complexity of multiple applications competing for resources. Generally, a queue is provided to manage requests from applications to use worker threads, such as a request to use a thread to access a resource. If all requests are treated equally, then a first-to-arrive request is assigned to a worker thread first. In some instances, some requests have a higher priority than others. In such a case, separate queues of requests are used for each priority level, and each priority level has its own pool of worker threads. A scheduler assigns threads to requests in queues based on time of arrival, and manages shared access to resources by multiple threads by making threads active and blocking or preempting threads based on priority.
With such a system, each worker thread has a fixed priority, and cannot change priority during execution; otherwise there is a risk of priority inversions. Also, with a pool of worker threads for each priority level, the number of priority levels is limited by system resources. Finally, such a system can experience dependency deadlocks.